<template>
  <el-form
    v-loading="loading"
    ref="skuForm"
    :model="skuForm"
    :rules="skuRules"
    size="small"
    class="sku-editor"
  >
    <div v-if="showSpecs && haveSpec" class="sku-editor-item">
      <span v-if="showLabel" class="label-text">规格信息：</span>
      <div class="spec-list">
        <div class="spec-list-tip">
          <span class="tip-label">提示：</span>
          <div class="tip-content">
            在输入框中输入不存在的规格或规格值后回车，即可添加自定义规格或规格值
            <br/>
            只有第一个规格可以添加规格值图片
          </div>
        </div>
        <template v-for="(sp, sp_index) in skuForm.selectedSpecs" >
          <el-form-item label="规格名：" class="spec-name">
            <el-select
              v-model="sp.spec_id"
              default-first-option
              @change="handleSpecChange"
            >
              <el-option
                v-for="option in specList"
                :key="option.spec_id"
                :label="option.spec_name"
                :value="option.spec_id"
                :disabled="computedDisabledSpec(option.spec_id)"
              />
            </el-select>
            <el-button icon="el-icon-delete" class="del-btn" @click="handleDeleteSpec(sp_index)"/>
            <el-checkbox v-if="sp_index === 0" label="规格图片" v-model="sp.has_spec_image"/>
          </el-form-item>
          <el-form-item label="规格值：" class="spec-values" :class="{'no-spec-val': sp.spec_value_list.length === 0}">
            <div v-for="(sv, sv_index) in sp.spec_value_list" :key="sv_index" class="spec-value-item">
              <div class="spec-value-select">
                <el-select
                  v-model="sv.spec_value_id"
                  default-first-option
                  @change="spec_val_id => handleSpecValChange(sp.spec_id, spec_val_id)"
                >
                  <el-option
                    v-for="option in getSpecValueList(sp.spec_id)"
                    :key="option.spec_value_id"
                    :label="option.spec_value"
                    :value="option.spec_value_id"
                    :disabled="computedDisabledSpecVal(sp.spec_id, option.spec_value_id)"
                  />
                </el-select>
                <el-button icon="el-icon-delete" class="del-btn" @click="handleDeleteSpecVal(sp_index, sv_index)"/>
              </div>
              <el-form-item
                label=""
                :prop="`selectedSpecs.${sp_index}.spec_value_list.${sv_index}.spec_image`"
                class="spec-value-form-item"
              >
                <el-upload
                  v-if="sp.has_spec_image"
                  accept="image/*"
                  list-type="picture-card"
                  :action="MixinUploadApi"
                  :file-list="sv.spec_image ? [{ url: sv.spec_image }] : undefined"
                  :on-success="file => handleSpecValImgUploadSuccess(sp_index, sv_index, file)"
                  :on-remove="() => handleSpecValImgRemove(sp_index, sv_index)"
                  :limit="1"
                  class="spec-value-upload"
                >
                  <i class="el-icon-plus"></i>
                </el-upload>
              </el-form-item>
            </div>
            <div class="spec-value-item" :class="{'has-img': sp.has_spec_image}">
              <el-button v-if="sp.spec_id" type="text" @click="handleAddSpecVal(sp_index)">添加规格值</el-button>
              <span v-else style="color: #999; font-size: 12px">请选择规格</span>
            </div>
          </el-form-item>
        </template>
        <el-form-item>
          <el-button type="primary" @click="handleAddSpec">添加规格</el-button>
        </el-form-item>
      </div>
    </div>
    <div class="sku-editor-item">
      <span v-if="showLabel" class="label-text">SKU信息：</span>
      <el-table :data="skuForm.skuList" border class="sku-table">
        <el-table-column label="规格" align="center" v-if="haveSpec">
          <template v-slot="{ row }">
            <span>{{ formatterSpecText(row) }}</span>
          </template>
        </el-table-column>
        <el-table-column v-for="item in tableColumns" :key="item.key" align="center">
          <template v-slot:header="{ row }">
            <div>
              <span>{{ item.name }}</span>
              <el-tooltip v-if="!!item.tip" effect="dark" :content="item.tip" placement="top">
                <i class="el-icon-warning" style="cursor: help"></i>
              </el-tooltip>
              <el-popover
                v-if="!!item.batch"
                v-model="item.show_batch"
                popper-class="sku-batch-popper"
                placement="top"
              >
                <el-form
                  size="mini"
                  label-width="80px"
                  label-position="right"
                  @submit.native.prevent
                >
                  <el-form-item v-if="item.batchForm.prefix !== false" label="前缀字符">
                    <el-input
                      v-model="item.batchForm.prefix"
                      :maxlength="20"
                      style="width: 100px;"
                      placeholder="选填"
                    />
                  </el-form-item>
                  <el-form-item :label="item.batchForm.initial_value_label">
                    <el-input-number
                      v-if="item.batchForm.initial_value_type === 'Number'"
                      v-model="item.batchForm.initial_value"
                      :controls="false"
                      :max="item.batchForm.initial_value_max"
                      placeholder="选填"
                      style="width: 100px"
                    />
                    <el-input
                      v-else
                      v-model="item.batchForm.initial_value"
                      :maxlength="item.batchForm.initial_value_maxlength"
                      placeholder="选填"
                      style="width: 100px"
                    />
                  </el-form-item>
                  <el-form-item v-if="item.batchForm.step !== false" label="递增步长">
                    <el-input-number
                      v-model="item.batchForm.step"
                      :controls="false"
                      :max="item.batchForm.step_max"
                      style="width: 100px"
                      placeholder="选填"
                    />
                  </el-form-item>
                  <el-form-item v-if="item.batchForm.pad_zero !== false" label="补零位数">
                    <el-input-number
                      v-model="item.batchForm.pad_zero"
                      :controls="false"
                      :max="item.batchForm.pad_zero_max"
                      style="width: 100px"
                      placeholder="选填"
                    />
                  </el-form-item>
                </el-form>
                <div style="text-align: right; margin: 0">
                  <el-button size="mini" type="text" @click="item.show_batch = false">取消</el-button>
                  <el-button type="primary" size="mini" @click="handleBatchSetSkuParams(item)">确定</el-button>
                </div>
                <i slot="reference" class="el-icon-brush batch-btn"></i>
              </el-popover>

            </div>
          </template>
          <template v-slot="{ row, $index }">
            <span v-if="item.readonly">{{ row[item.key] || '-' }}</span>
            <el-form-item
              v-else
              :prop="`skuList.${$index}.${item.key}`"
              :class="{'hide-message': !showFormMessage}"
            >
              <el-input-number
                v-if="item.type === 'Number'"
                v-model="row[item.key]"
                :max="item.max"
                :controls="false"
                :disabled="item.disabled"
                style="width: 100%"
              />
              <el-input
                v-else
                v-model="row[item.key]"
                :disabled="item.disabled"
                :maxlength="item.maxlength"
                style="text-align: center"
              />
            </el-form-item>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </el-form>
</template>

<script>
import * as Helper from './helper'

export default {
  name: 'SkuEditor',
  props: {
    // 扩展参数
    extendedParams: {
      type: Array,
      required: false,
      default: () => ([])
    },
    // 显示表单错误信息
    showFormMessage: {
      type: Boolean,
      required: false,
      default: false
    },
    // 是否显示Label
    showLabel: {
      type: Boolean,
      required: false,
      default: true
    },
    // 是否显示规格
    showSpecs: {
      type: Boolean,
      required: false,
      default: true
    },
    categoryId: {
      type: String,
      default: ''
    },
    goodsInfo: {
      type: Object,
      default: {}
    },
    haveSpec: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      loading: false,
      // goodsInfo: '',
      skuForm: {
        selectedSpecs: [],
        skuList: []
      },
      specList: [],
      tableColumns: [],
      rawSkuList: []
    }
  },
  computed: {
    params() {
      return Helper.mergeParams(this.extendedParams, this.haveSpec)
    },
    skuRules() {
      return Helper.computedSkuRules(this.skuForm, this.params)
    }
  },
  mounted() {
    this.init()
  },
  watch: {
    // 监听已选规格，自动生成表单
    'skuForm.selectedSpecs': {
      deep: true,
      handler: 'makeTableForm'
    },
    haveSpec: {
      handler(val) {
        this.skuForm.selectedSpecs = []
        this.skuForm.skuList = []
      }
    },
    categoryId: {
      handler(val) {
        if (val) {
          this.getSpecList()
        }
      },
      immediate: true
    },
    goodsInfo: {
      handler(val) {
        if (val.product_list) {
          this.init()
        }
      },
      immediate: true
    }
  },
  methods: {
    // 初始化数据
    async init() {
      try {
        this.loading = true
        const goodsInfo = this.goodsInfo
        if (goodsInfo.product_list) {
          // 获取规格列表
          this.getSpecList()
          this.skuForm.skuList = Helper.cloneJson(goodsInfo.product_list)
          this.rawSkuList = Helper.cloneJson(goodsInfo.product_list)
          // 初始化商品SKU中已选择的规格信息
          this.skuForm.selectedSpecs = Helper.initSelectedSpecs(this.skuForm.skuList)
        }
        if (!this.haveSpec) {
          this.makeTableForm()
        }
      } finally {
        this.loading = false
      }
    },
    // 获取规格列表
    async getSpecList() {
      const category_id = this.goodsInfo.category_id || this.categoryId
      await Helper.getSpecsByCategoryId(category_id).then(res => {
        this.specList = res
        this.makeTableForm()
      })
    },
    // 获取商品sku信息
    // async getSkuList() {
    //   const skuList = await Helper.getGoodsSkus(this.goodsId)
    //   this.skuForm.skuList = Helper.cloneJson(skuList)
    //   this.rawSkuList = Helper.cloneJson(skuList)
    // },
    // 生成表格表单
    makeTableForm() {
      const specs = Helper.getSelectedSpecsFormSpecList(this.skuForm.selectedSpecs, this.specList)
      const table = Helper.makeTableForm(specs, this.params, this.skuForm.skuList, this.haveSpec)
      this.tableColumns = table.columns
      this.skuForm.skuList = table.data
      // // 如果是单规格，不用选择规格，默认给一个sku
      // if(!this.haveSpec) {
      //   this.skuForm.skuList = [{}]
      // }
    },
    // 获取规格下的规格值列表
    getSpecValueList(spec_id) {
      const specVal = this.specList.find(item => item.spec_id === spec_id)
      return specVal ? specVal.value_list : []
    },
    // 计算要禁用的规格
    computedDisabledSpec(spec_id) {
      return this.skuForm.selectedSpecs.map(item => item.spec_id).includes(spec_id)
    },
    // 计算要禁用的规格值
    computedDisabledSpecVal(spec_id, spec_value_id) {
      return this.skuForm
        .selectedSpecs.find(item => item.spec_id === spec_id)
        .spec_value_list.map(item => item.spec_value_id)
        .includes(spec_value_id)
    },
    // 添加规格
    handleAddSpec() {
      if (!this.goodsInfo.category_id && !this.categoryId) {
        this.$message.error('请先选择商品类别！')
        return
      }
      this.skuForm.selectedSpecs.push({ spec_id: '', has_spec_image: false, spec_value_list: [] })
    },
    // 添加规格值
    handleAddSpecVal(index) {
      this.skuForm.selectedSpecs[index].spec_value_list.push({ spec_value_id: '' })
    },
    // 规格发生改变
    async handleSpecChange(spec_id) {
      let spec = this.specList.find(sp => sp.spec_id === spec_id)
      const selectedSpec = this.skuForm.selectedSpecs.find(sp => sp.spec_id === spec_id)
      selectedSpec.spec_id = spec.spec_id
      selectedSpec.spec_value_list = []
    },
    // 规格值发生改变
    async handleSpecValChange(spec_id, spec_val_id) {
      let specVal = ''
      const specValueList = this.specList.find(sp => sp.spec_id === spec_id).value_list
      if (Array.isArray(specValueList)) {
        specVal = specValueList.find(sv => sv.spec_value_id === spec_val_id)
      }
      if (specVal) return
    },
    // 格式化规格文字信息
    formatterSpecText(row) {
      if (!Array.isArray(row.spec_list)) return '/'
      return row.spec_list.map(sv => sv.spec_value).join('/')
    },
    // 移除规格
    async handleDeleteSpec(sp_index) {
      try {
        const spec = this.skuForm.selectedSpecs[sp_index]
        if (spec.spec_id) {
          let msg = '确定要移除这个规格吗?'
          let has_spec = false
          if (Array.isArray(spec.spec_value_list)) {
            has_spec = spec.spec_value_list.filter(sv => sv.spec_value_id).length !== 0
          }
          if (has_spec) msg = '移除后规格维度将发生改变，会导致已有规格数据丢失！确定要移除吗？'
          await this.$confirm(msg, '提示', { type: has_spec ? 'error' : 'warning' })
        }
        this.skuForm.selectedSpecs.splice(sp_index, 1)
      } catch (e) {
        //
      }
    },
    // 移除规格值
    async handleDeleteSpecVal(sp_index, sv_index) {
      try {
        const spec_value_list = this.skuForm.selectedSpecs[sp_index].spec_value_list
        if (spec_value_list[sv_index].spec_value_id) {
          let msg = '确定要移除这个规格值吗?'
          let last_spc_val = false
          if (spec_value_list.length === 1) {
            last_spc_val = true
            msg = '最后一个规格值移除后规格维度将发生改变，会导致已有规格数据丢失！确定要移除吗？'
          }
          await this.$confirm(msg, '提示', { type: last_spc_val ? 'error' : 'warning' })
        }
        this.skuForm.selectedSpecs[sp_index].spec_value_list.splice(sv_index, 1)
      } catch (e) {
        //
      }
    },
    // 规格值图片上传成功
    handleSpecValImgUploadSuccess(sp_index, sv_index, file) {
      this.$set(this.skuForm.selectedSpecs[sp_index].spec_value_list[sv_index], 'spec_image', file.url)
      this.$refs.skuForm.validateField([`selectedSpecs.${sp_index}.spec_value_list.${sv_index}.spec_image`])
    },
    // 移除规格值图片
    handleSpecValImgRemove(sp_index, sv_index) {
      this.skuForm.selectedSpecs[sp_index].spec_value_list[sv_index].spec_image = ''
    },
    // 批量设置SKU参数
    async handleBatchSetSkuParams(param) {
      try {
        await this.$confirm('当前操作会覆盖已有值，确定吗？', '提示', { type: 'warning' })
        let { prefix, step, initial_value, pad_zero } = Helper.cloneJson(param.batchForm)
        this.skuForm.skuList.forEach(sku => {
          let val = ''
          if (prefix !== false && prefix) val += prefix
          if (step !== false && step) initial_value += step
          if (pad_zero !== false && pad_zero > 1) {
            val += String(initial_value).padStart(pad_zero, '0')
          } else {
            val += initial_value
          }
          this.$set(sku, param.key, val || '')
        })
      } catch (e) {
        // console.log('e: ', e)
      }
    },
    // 保存
    submit() {
      return new Promise((resolve, reject) => {
        if (this.skuForm.skuList.length === 0) {
          reject()
          return
        }
        this.$refs.skuForm.validate(async valid => {
          if (!valid) {
            // this.$message.error('表单填写有误，请核对带有红色边框的表单项！')
            reject()
            return
          }
          const skus = Helper.cloneJson(this.skuForm.skuList)
          resolve(skus)
          // try {
          //   await Helper.saveGoodsSkus(this.goodsId, skus)
          //   resolve()
          // } catch (e) {
          //   //
          // }
        })
      })
    }
  }
}
</script>
<style lang="scss" scoped>
@import "./styles";
</style>
<style lang="scss">
.sku-batch-popper {
  .el-form-item {
    margin-bottom: 5px !important;
    .el-input__inner {
      text-align: center;
    }
    .el-form-item__label {
      font-size: 12px;
    }
  }
}
</style>
